﻿using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Collections.ObjectModel;
using System.ComponentModel;
// Import model classes!
using System.Collections;
using DlhSoft.Windows.Controls;
using UTC_Project_Manager.Model.Infrastructure;
using DlhSoft.Windows.Data;

namespace UTC_Project_Manager.Controls
{
    /// <summary>
    /// TaskManager
    /// </summary>
    public partial class GanttControl : UserControl
    {
        private int counter = 0;
        
        public delegate void PassDescriptionValues(Hashtable descValuesHashTable);
        public static event PassDescriptionValues descriptionValuesEvent;

        public delegate void CleanDescriptionValues();
        public static event CleanDescriptionValues cleanDescriptionValuesEvent;

        private bool isInit = false;

        public GanttControl()
        {
            InitializeComponent();
            this.GanttChartView.ItemContextMenu = GetContextMenu();
            //App.MyConfig.taskItems.CollectionChanged += new NotifyCollectionChangedEventHandler(taskItems_CollectionChanged);
            App.MyConfig.taskItems.ListChanged += new ListChangedEventHandler(taskItems_ListChanged);
            //NewReunionControl.newReunionCreatedEvent += new NewReunionControl.NewReunionEvent(NewReunionControl_newReunionCreatedEvent);
            if (!isInit)
            {
                InitializeTask();
                isInit = true;
            }
        }

        // Add reunions created in NewReunionControl to taskItems and Task List
        void NewReunionControl_newReunionCreatedEvent(Meeting meeting)
        {
            int index = getLastTaskIndex();
            String indexString = Convert.ToString(index);
            App.MyConfig.taskItems.Add(new UTC_Project_Manager.Model.Infrastructure.TaskItem { Content = meeting.Title, Start = meeting.Date, IsMilestone = true, IndexString = indexString });
            App.MyConfig.OurProject.Tasks.Add(new ProjectTask { Content = meeting.Title, Start = meeting.Date, IsMilestone = true, IndexString = indexString, Description = meeting.Description });
        }

        public void InitializeTask() {
            // Populate ItemsSource
            this.TaskListView.ItemsSource = App.MyConfig.taskItems;
            this.GanttChartView.ItemsSource = App.MyConfig.taskItems;
            // Populate TaskManagerSource
            this.TaskListView.TaskManagerSource = App.MyConfig.taskManager;
            this.GanttChartView.TaskManagerSource = App.MyConfig.taskManager;

            if (App.MyConfig.taskItems.Count > 0){
                //this.GanttChartView.Schedule = Schedule.
                this.GanttChartView.TimelinePageStart = App.MyConfig.taskItems[0].Start;
                TimeSpan duration = (TimeSpan)(App.MyConfig.taskItems[App.MyConfig.taskItems.Count-1].Finish - App.MyConfig.taskItems[0].Start);
                if(duration.Days > 30)
                    this.GanttChartView.TimelinePageDuration = duration;
                else this.GanttChartView.TimelinePageDuration = TimeSpan.Parse("60.00:00:00");
            }
                

            // Add a new ResourceItem called "All", to be able to show all the task later
            ObservableCollection<ResourceItem> resourceItems = new ObservableCollection<ResourceItem>();
            foreach (ResourceItem item in App.MyConfig.assignableResourceItems)
            {
                resourceItems.Add(item);
            }
            resourceItems.Add(new ResourceItem { Content = "All" });
            // Populate the ResourceFilterComboBox
            //this.ResourceFilterComboBox.ItemsSource = resourceItems;
        }

        //private void filterTaskByMember(object selectedMemberObject)
        //{
        //    // Collect the resource to use for filtering tasks.
        //    ResourceItem memberResourceItem = selectedMemberObject as ResourceItem;
        //    // Set the Filter property of the default collection view to apply filtering.
        //    ICollectionView taskCollectionView = CollectionViewSource.GetDefaultView(GanttChartView.ItemsSource);
        //    // Reset the filter
        //    if (memberResourceItem.Content.ToString() == "All")
        //        taskCollectionView.Filter = null;
        //    else
        //    {
        //        taskCollectionView.Filter =
        //            (Predicate<object>)delegate(object item)
        //            {
        //                // A task should be included in the view if it has at least one assignment referring the selected resource.
        //                UTC_Project_Manager.Model.Infrastructure.TaskItem taskItem = item as UTC_Project_Manager.Model.Infrastructure.TaskItem;
        //                return (from assignmentItem in taskItem.Assignments
        //                        where assignmentItem.ResourceItem == memberResourceItem
        //                        select assignmentItem).Count() > 0;
        //            };
        //    }
        //}

        //private void ResourceFilterComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        //{
        //    filterTaskByMember(ResourceFilterComboBox.SelectedItem);
        //}

        // Create the ContextMenu for the Task.
        private ContextMenu GetContextMenu()
        {
            MenuItem descriptionMenuItem;
            ContextMenu contextMenu = new ContextMenu();

            descriptionMenuItem = new MenuItem();
            descriptionMenuItem.Header = "Description";
            
            /*
            Image imgDescription = new Image();
            BitmapImage myBitmapImage = new BitmapImage();
            myBitmapImage.BeginInit();
            myBitmapImage.UriSource = new Uri(@"/Ressources/Icons/edit-paste.png");
            myBitmapImage.EndInit();
            imgDescription.Source = myBitmapImage;
            descriptionMenuItem.Icon = imgDescription;
            */

            contextMenu.Items.Add(descriptionMenuItem);
            contextMenu.AddHandler(MenuItem.ClickEvent, new RoutedEventHandler(ContextMenu_Click));

            return contextMenu;
        }

        // Handler for the ContextMenu
        private void ContextMenu_Click(object sender, RoutedEventArgs e)
        {
            // Actual menu item
            String header = ((MenuItem)e.Source).Header.ToString();
            
            FrameworkElement element = e.OriginalSource as FrameworkElement;
            if (element == null)
                return;
            object dataContext = element.DataContext;
            if (!(element is Panel) && dataContext == null)
                return;

            // Get data context details.
            if (dataContext is Task)
            {
                Task task = (Task)dataContext;
                // Select current task in  TaskListView (To be able to delete if the user want to)
                this.TaskListView.SelectedIndex = Convert.ToInt32(task.IndexString) - 1;
                // Show Description
                if (header == "Description") 
                {
                    callDescriptionEvent(task.Content, task.IndexString, task.AssignmentsString);
                }
            }
            /*
            else if (dataContext is Predecessor)
            {
                Predecessor predecessor = (Predecessor)dataContext;
                informationBuilder.AppendLine(string.Format("Details: Dependency line for predecessor {0} ({1}) of task {2} ({3})", predecessor.Task.IndexString, predecessor.Task.Content, predecessor.ParentTask.IndexString, predecessor.ParentTask.Content));
            }
            */
        }

        // This event fires 3 times! so we only want to execute the handler once :)
        private void TaskListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (counter == 0)
            {
                TreeListView treeListView = e.OriginalSource as TreeListView;
                if (treeListView == null) return;
                UTC_Project_Manager.Model.Infrastructure.TaskItem taskItem = treeListView.SelectedItem as UTC_Project_Manager.Model.Infrastructure.TaskItem;
                if (taskItem != null)
                {
                    callDescriptionEvent(taskItem.Content, taskItem.IndexString, taskItem.AssignmentsString);
                    counter++;
                }
            }
            else counter++;
            if (counter == 3) counter = 0;
        }

        private void callDescriptionEvent(object Content, String IndexString, String MemberName) {
            Hashtable descValues = new Hashtable();
            descValues.Add("TaskListView", this.TaskListView);
            descValues.Add("TaskName", Content);
            descValues.Add("TaskIndexString", IndexString);
            if (MemberName != null)
                descValues.Add("MemberName", MemberName);
            else
                descValues.Add("MemberName", "None");
            // Raise the event passing the Hashtable as an argument
            // to the EventHandler in the DescriptionControl
            descriptionValuesEvent(descValues);
        }

        private void TaskListView_NewTask(object sender, NewItemEventArgs e)
        {
            String index = Convert.ToString(getLastTaskIndex()+1);
            e.Item = new UTC_Project_Manager.Model.Infrastructure.TaskItem { Content = "Nouvelle tâche", Start = DateTime.Today, Effort = TimeSpan.Parse("08:00:00"), IndexString = index };
            App.MyConfig.OurProject.Tasks.Add(new ProjectTask { Content = "Nouvelle tâche", Start = DateTime.Today, Effort = TimeSpan.Parse("08:00:00"), IndexString = index });
        }

        // We have two reference to GanttControl so every method is going to be called twice! >.<
        void taskItems_ListChanged(object sender, ListChangedEventArgs e)
        {
            BindingList<UTC_Project_Manager.Model.Infrastructure.TaskItem> taskItems = sender as BindingList<UTC_Project_Manager.Model.Infrastructure.TaskItem>;
            int index = e.NewIndex;
            switch (e.ListChangedType)
            {
                case ListChangedType.ItemDeleted:
                    App.MyConfig.OurProject.Tasks.RemoveAt(index);
                    cleanDescriptionValuesEvent();
                    break;
                case ListChangedType.ItemChanged:
                    callDescriptionEvent(taskItems[index].Content, taskItems[index].IndexString, taskItems[index].AssignmentsString);
                    updateTask(taskItems[index],index);
                    break;
            }
        }

        public void updateTask(UTC_Project_Manager.Model.Infrastructure.TaskItem taskItem, int index) {
            ProjectTask pTask = App.MyConfig.OurProject.Tasks.ElementAt(index);
            pTask.Content = taskItem.Content;
            pTask.IndexString = taskItem.IndexString;
            pTask.Indentation = taskItem.Indentation;

            pTask.Start = taskItem.Start;
            pTask.Finish = taskItem.Finish;

            pTask.Duration = taskItem.Duration;
            pTask.Effort = taskItem.Effort;
            pTask.CompletedEffort = taskItem.CompletedEffort;
            pTask.Completion = taskItem.Completion;

            pTask.IsCompleted = taskItem.IsCompleted;
            pTask.IsExpanded = taskItem.IsExpanded;
            pTask.IsMilestone = taskItem.IsMilestone;

            pTask.AssignmentsString = taskItem.AssignmentsString;
            pTask.PredecessorsString = taskItem.PredecessorsString;

            App.MyConfig.OurProject.Tasks.ElementAt(index);
        }

        public int getLastTaskIndex()
        {
            if(App.MyConfig.OurProject.Tasks != null && App.MyConfig.OurProject.Tasks.Count > 0)
                return Convert.ToInt32(App.MyConfig.OurProject.Tasks.Last().IndexString);
            else return 0;
        }

        private void taskListExpander_Expanded(object sender, RoutedEventArgs e)
        {
            //this.taskListExpander.Header = "Hide";
        }

        private void taskListExpander_Collapsed(object sender, RoutedEventArgs e)
        {
            //this.taskListExpander.Header = "Show";
        }
    }
}
